package com.xmtlxx.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.xmtlxx.common.core.domain.PageQuery;
import com.xmtlxx.common.core.domain.entity.*;
import com.xmtlxx.common.core.page.TableDataInfo;
import com.xmtlxx.common.enums.ModelBussType;
import com.xmtlxx.common.helper.LoginHelper;
import com.xmtlxx.common.utils.DateUtils;
import com.xmtlxx.common.utils.StringUtils;
import com.xmtlxx.common.utils.push.PushUtils;
import com.xmtlxx.common.utils.push.domain.PushContent;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmtlxx.system.domain.NoticeUser;
import com.xmtlxx.system.domain.SysNotice;
import com.xmtlxx.system.domain.SysOss;
import com.xmtlxx.system.domain.bo.SysModelBo;
import com.xmtlxx.system.domain.bo.SysNodeBo;
import com.xmtlxx.system.domain.bo.SysOperatorBo;
import com.xmtlxx.system.domain.vo.SysFormVo;
import com.xmtlxx.system.domain.vo.SysModelVo;
import com.xmtlxx.system.domain.vo.SysWorklogVo;
import com.xmtlxx.system.mapper.*;
import com.xmtlxx.system.service.ISysModelService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 业务模型Service业务层处理
 *
 * @author xmtlxx
 * @date 2022-04-24
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SysModelServiceImpl implements ISysModelService {

    private final SysModelMapper baseMapper;

    private final SysFormMapper sysFormMapper;

    private final SysProcessMapper processMapper;

    private final SysNodeMapper nodeMapper;

    private final SysWorklogMapper worklogMapper;

    private final SysUserMapper userMapper;

    private final SysOperatorMapper operatorMapper;

    private final SysDeptMapper deptMapper;

    private final SysRoleMapper roleMapper;

    private final SysNoticeMapper noticeMapper;

    private final NoticeUserMapper noticeUserMapper;

    private final SysOssMapper sysOssMapper;

    /**
     * 查询业务模型
     *
     * @param modelid 业务模型主键
     * @return 业务模型
     */
    @Override
    public SysModelVo queryById(String modelid){
        return baseMapper.selectVoById(modelid);
    }

    /**
     * 查询业务模型列表
     *
     * @param bo 业务模型
     * @return 业务模型
     */
    @Override
    public TableDataInfo<SysModelVo> queryPageList(SysModelBo bo, PageQuery pageQuery) {
        Page<SysModelVo> result = baseMapper.selectPageSysModelList(pageQuery.build(),bo);
        return TableDataInfo.build(result);
    }

    /**
     * 查询业务模型列表
     *
     * @param bo 业务模型
     * @return 业务模型
     */
    @Override
    public List<SysModelVo> queryList(SysModelBo bo) {
        return baseMapper.selectSysModelList(bo);
    }

    private LambdaQueryWrapper<SysModel> buildQueryWrapper(SysModelBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SysModel> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getModelno()), SysModel::getModelno, bo.getModelno());
        lqw.eq(StringUtils.isNotBlank(bo.getBusstype()), SysModel::getBusstype, bo.getBusstype());
        lqw.like(StringUtils.isNotBlank(bo.getName()), SysModel::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getWid()), SysModel::getWid, bo.getWid());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysModel::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增业务模型
     *
     * @param bo 业务模型
     * @return 结果
     */
    @Override
    public Boolean insertByBo(SysModelBo bo, List<SysFormVo> items) {
        SysModel add = BeanUtil.toBean(bo, SysModel.class);
        validEntityBeforeSave(add);

        //填充UUID
        add.setModelid(IdUtil.simpleUUID());
        add.setDelFlag("0");
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setModelid(add.getModelid());
        }

        if(items != null && items.size() > 0){
           for(SysFormVo item : items){
               SysForm form = new SysForm();
               form.setFormid(IdUtil.simpleUUID());
               form.setItemId(item.getItemId());
               form.setMid(add.getModelid());
               form.setTypeId(item.getTypeId());
               sysFormMapper.insert(form);
           }
        }

        return flag;
    }

    /**
     * 修改业务模型
     *
     * @param bo 业务模型
     * @return 结果
     */
    @Override
    public Boolean updateByBo(SysModelBo bo, List<SysFormVo> items) {
        SysModel update = BeanUtil.toBean(bo, SysModel.class);
        validEntityBeforeSave(update);

        LambdaQueryWrapper<SysForm> lqw = Wrappers.lambdaQuery();
        lqw.eq(SysForm::getMid,update.getModelid());
        sysFormMapper.delete(lqw);
        if(items != null && items.size() > 0){
            for(SysFormVo item : items){
                SysForm form = new SysForm();
                form.setFormid(IdUtil.simpleUUID());
                form.setItemId(item.getItemId());
                form.setMid(update.getModelid());
                form.setTypeId(item.getTypeId());
                sysFormMapper.insert(form);
            }
        }

        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(SysModel entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除业务模型
     *
     * @param ids 需要删除的业务模型主键
     * @return 结果
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        for(String id : ids){
//           SysModel enty = baseMapper.selectById(id);
//           enty.setDelFlag("1");
           baseMapper.deleteById(id);
        }
        return true;
    }

    /**
     * 流程处理
     *  起始状态，创建业务流程记录，并记录一条流程开始日志及一条下一个节点待办记录
     * @param type
     * @param bussid
     * @param mid
     * @return
     */
    @Override
    public Boolean startModelWorkflow(String type, String bussid, String mid) {
        SysModel model = baseMapper.selectById(mid);
        ModelBussType bussType = ModelBussType.getBussTypeByCode(type);
        Long operator = LoginHelper.getUserId();
        SysNodeBo nodeParam = new SysNodeBo();
        nodeParam.setWid(model.getWid());
        nodeParam.setDelFlag("0");
        List<SysNode> nodes = nodeMapper.selectSysNodeList(nodeParam);
        SysUser user = userMapper.selectUserById(operator);
        String startId = null;
        String nextId = null;
        String title = "";
        String content = "";

        List<String> toUser = new ArrayList<>();

        if(nodes != null && nodes.size() > 0){
            Integer index = 0;

            //判断是否重新开始 是的话，重置Process,结束待办worklog
            LambdaQueryWrapper<SysProcess> processParam = Wrappers.lambdaQuery();
            processParam.eq(SysProcess::getBussid,bussid);
            processParam.eq(SysProcess::getMid,mid);
            processParam.orderByAsc(SysProcess::getSeq);
            List<SysProcess> processes = processMapper.selectList(processParam);
            if(processes != null && processes.size() > 0){
                for(SysProcess process : processes){
                    SysNode node = nodeMapper.selectById(process.getNid());
                    process.setActime(null);

                    process.setOperator(null);
                    process.setAction(null);
                    if(StringUtils.isNotBlank(node.getSflag()) && node.getSflag().equals("Y")){
                        process.setStatus("2");
                        process.setOperator(user.getNickName());
                        process.setActime(new Date());
                        process.setAction("1");
                        startId = process.getPid();
                    }else{
                        process.setStatus("0");
                    }
                    if(index == 1){
                        process.setStatus("1");
                        nextId =  process.getPid();
                    }
                    processMapper.updateById(process);
                    index ++;
                }

                //结束待办日志
                LambdaQueryWrapper<SysWorklog> worklogParam = Wrappers.lambdaQuery();
                worklogParam.eq(SysWorklog::getObjid,bussid);
                worklogParam.eq(SysWorklog::getStatus,"0");
                SysWorklog worklog = new SysWorklog();
                worklog.setUserId(user.getUserId());
                worklog.setUserName(user.getNickName());
                worklog.setDeptId(user.getDeptId());
                worklog.setStatus("1");
                worklog.setMemo(user.getNickName()+" 编辑表单，重新提交审核。");
                worklogMapper.update(worklog,worklogParam);

            }else{
                for(SysNode node : nodes){
                    SysProcess process = new SysProcess();
                    process.setPid(IdUtil.simpleUUID());
                    process.setBussid(bussid);
                    process.setMid(mid);
                    process.setWid(model.getWid());
                    process.setNid(node.getNid());
                    process.setSeq(node.getSort());
                    process.setName(node.getName());
                    process.setMemo(node.getMemo());
                    process.setDeptId(user.getDeptId());
                    if(StringUtils.isNotBlank(node.getSflag()) && node.getSflag().equals("Y")){
                        process.setStatus("2");
                        process.setOperator(user.getNickName());
                        process.setActime(new Date());
                        process.setAction("1");
                        startId = process.getPid();
                    }else{
                        process.setStatus("0");
                    }
                    if(index == 1){
                        process.setStatus("1");
                        nextId =  process.getPid();
                    }
                    processMapper.insert(process);
                    index ++;
                }
            }


            //写入一条开始日志
            SysWorklog startlog = new SysWorklog();
            startlog.setLogid(IdUtil.simpleUUID());
            startlog.setWid(model.getWid());
            startlog.setNid(nodes.get(0).getNid());
            startlog.setObjid(bussid);
            startlog.setName(nodes.get(0).getName());
            startlog.setBusstype(bussType.getCode());
            startlog.setRoute(bussType.getRoute());
            startlog.setOperatorid(operator);
            startlog.setOtype("0");
            startlog.setOname(user.getNickName());
            startlog.setUserId(operator);
            startlog.setDeptId(user.getDeptId());
            startlog.setTitle(bussType.getTitle());
            startlog.setContent(startlog.getOname()+" "+DateUtils.parseDateToStr("yyyy-MM-dd HH:mm",new Date()) +" 提交 "+bussType.getTitle());
            startlog.setStatus("1");//已办
            startlog.setAction("1");
            startlog.setPid(startId);
            startlog.setUserName(user.getNickName());
            worklogMapper.insert(startlog);

            //写入一条下一个待办记录
            //获取经办人
            SysNode nextNode = nodes.get(1);
            SysOperatorBo operatorParam = new SysOperatorBo();
            operatorParam.setNid(nextNode.getNid());
            operatorParam.setType("0");
            List<SysOperator> operators = operatorMapper.selectSysOperatorList(operatorParam);

            if(operators != null && operators.size() > 0){
                for(SysOperator op : operators){
                    SysWorklog nextlog = new SysWorklog();
                    nextlog.setLogid(IdUtil.simpleUUID());
                    nextlog.setWid(model.getWid());
                    nextlog.setNid(nextNode.getNid());
                    nextlog.setObjid(bussid);
                    nextlog.setName(nextNode.getName());
                    nextlog.setBusstype(bussType.getCode());
                    nextlog.setRoute(bussType.getRoute());
                    nextlog.setOtype(nextNode.getOtype());
                    nextlog.setOperatorid(op.getObjid());
                    nextlog.setOname(op.getName());
                    nextlog.setTitle(bussType.getTitle());
                    nextlog.setContent(startlog.getContent()+",请及时处理。");
                    nextlog.setStatus("0");//待办
                    nextlog.setPrelogid(startlog.getLogid());
                    nextlog.setPreid(startlog.getUserId());
                    nextlog.setPrenid(startlog.getNid());
                    nextlog.setDeptId(startlog.getDeptId());
                    nextlog.setPid(nextId);
                    worklogMapper.insert(nextlog);
                    toUser.addAll(getOperators(nextNode.getOtype(),op.getObjid().toString()));
                    title = nextlog.getTitle();
                    content = nextlog.getContent();
                }
            }
        }
        if(toUser != null && toUser.size() > 0){
            sendNotice(toUser,user.getDeptId(),title,content);
        }
        return true;
    }

    /**
     * 流程节点处理
     *  1、记录当前节点处理信息：
     *     状态：0-待执行；1-当前节点(正在执行)；2-已执行
     *     执行结果：0-驳回；1-通过；2-不通过；3-转办；
     *  2、通过：生成下一个节点待办处理 status = 2已执行
     *     不通过：生成上一个节点待办处理
     * @param worklogvo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysProcess nodeDeal(SysWorklogVo worklogvo) {
        SysWorklog worklog = new SysWorklog();
        BeanUtil.copyProperties(worklogvo,worklog);
        List<String> toUser = new ArrayList<>();
        Long deptId = LoginHelper.getDeptId();
        String title = "";
        String content = "";
        //日志处理 标记已执行
        worklog.setUserId(LoginHelper.getUserId());
        worklog.setUserName(LoginHelper.getNickname());
        worklog.setDeptId(LoginHelper.getDeptId());
        worklog.setStatus("1");//已办


        //多个执行人时，其他待办状态维护已办
        LambdaQueryWrapper<SysWorklog> logqw = Wrappers.lambdaQuery();
        logqw.eq(SysWorklog::getObjid,worklog.getObjid());
        logqw.eq(SysWorklog::getPid,worklog.getPid());
        logqw.eq(SysWorklog::getStatus,"0");
        List<SysWorklog> curLogs = worklogMapper.selectList(logqw);
        if(curLogs != null && curLogs.size() > 0){
            curLogs.forEach(item->{
                item.setUserId(LoginHelper.getUserId());
                item.setUserName(LoginHelper.getNickname());
                item.setDeptId(LoginHelper.getDeptId());
                item.setStatus("1");//已办
                worklogMapper.updateById(item);
            });
        }


        SysWorklog preLog = worklogMapper.selectById(worklog.getPrelogid());

        //流程节点处理
        SysProcess process = processMapper.selectById(worklog.getPid());
        process.setActime(new Date());

        process.setOperator(worklog.getUserName());
        process.setAction(worklog.getAction());
        process.setStatus("2");
        SysProcess result = process;

        SysWorklog newLog = new SysWorklog();
        switch (process.getAction()){
            case "0"://驳回：返回上一节点，根据前一个日志，生成一条待办记录
                process.setStatus("0");
                BeanUtil.copyProperties(preLog,newLog);
                newLog.setLogid(IdUtil.simpleUUID());
                newLog.setCreateBy(null);
                newLog.setCreateTime(null);
                newLog.setUpdateBy(null);
                newLog.setUpdateTime(null);
                newLog.setAction("0");//被驳回
                newLog.setMemo("");
                newLog.setPic("");
                newLog.setContent(
                    preLog.getTitle()+
                        " 被 "+worklog.getUserName()+
                        " 驳回"+(StringUtils.isNotBlank(worklog.getMemo())?"【"+worklog.getMemo()+"】":"")+
                        ",请及时处理。");
                worklog.setContent(worklog.getUserName()+
                    " 驳回 "+preLog.getTitle()+(StringUtils.isNotBlank(worklog.getMemo())?"【"+worklog.getMemo()+"】":"")+
                    "。");
                newLog.setStatus("0");//待办
//                newLog.setPrelogid(worklog.getLogid());
//                newLog.setPreid(worklog.getUserId());
//                newLog.setPrenid(worklog.getNid());
                worklogMapper.insert(newLog);

                SysProcess preProcess = processMapper.selectById(preLog.getPid());
                preProcess.setStatus("1");
                processMapper.updateById(preProcess);
                result = preProcess;

                toUser.add(newLog.getUserId()+"");
                title = preLog.getTitle()+" 被驳回";
                content = newLog.getContent();
                deptId = preLog.getDeptId();

                break;
            case "1"://通过：进入下一个节点
                worklog.setContent(worklog.getUserName()+
                    " 已处理 "+preLog.getTitle()+(StringUtils.isNotBlank(worklog.getMemo())?"【"+worklog.getMemo()+"】":"")+
                    "。");
                LambdaQueryWrapper<SysProcess> lqw = Wrappers.lambdaQuery();
                lqw.eq(SysProcess::getBussid,worklog.getObjid());
                lqw.gt(SysProcess::getSeq,process.getSeq());
                lqw.orderByAsc(SysProcess::getSeq);
                List<SysProcess> processes = processMapper.selectList(lqw);


                if(processes != null && processes.size() > 0){
                    SysProcess nextProcess = processes.get(0);
                    nextProcess.setStatus("1");//当前执行

                    SysNode nextNode = nodeMapper.getSysNodeById(nextProcess.getNid());
                    if(StringUtils.isNotBlank(nextNode.getEflag())
                        && nextNode.getEflag().equals("Y")){
//                        nextProcess.setStatus("1");//结束 写入一条待办日志
//                        nextProcess.setOperator(worklog.getUserName());
//                        nextProcess.setActime(process.getActime());

                        //获取发起人信息
                        lqw = Wrappers.lambdaQuery();
                        lqw.eq(SysProcess::getBussid,worklog.getObjid());
                        lqw.orderByAsc(SysProcess::getSeq);

                        List<SysProcess> list = processMapper.selectList(lqw);
                        SysProcess startProcess = list.get(0);
                        LambdaQueryWrapper<SysWorklog> wlqw = Wrappers.lambdaQuery();
                        wlqw.eq(SysWorklog::getPid,startProcess.getPid());
                        wlqw.orderByAsc(SysWorklog::getCreateTime);

                        List<SysWorklog> wlogs = worklogMapper.selectList(wlqw);

                        SysWorklog firstLog = wlogs.get(0);

                        SysWorklog nextlog = new SysWorklog();

                        nextlog.setLogid(IdUtil.simpleUUID());
                        nextlog.setWid(worklog.getWid());
                        nextlog.setNid(nextNode.getNid());
                        nextlog.setObjid(worklog.getObjid());
                        nextlog.setName(nextNode.getName());
                        nextlog.setBusstype(worklog.getBusstype());
                        nextlog.setRoute(worklog.getRoute());
                        nextlog.setOtype(firstLog.getOtype());
                        nextlog.setOperatorid(firstLog.getOperatorid());
                        nextlog.setOname(firstLog.getOname());
                        nextlog.setTitle(worklog.getTitle());
                        nextlog.setContent(worklog.getTitle()+" 已完成,请及时关注。");
                        nextlog.setStatus("0");//已办
//                        nextlog.setAction("1");
                        nextlog.setPrelogid(worklog.getLogid());
                        nextlog.setPreid(worklog.getUserId());
                        nextlog.setPrenid(worklog.getNid());
                        nextlog.setPid(nextProcess.getPid());
                        nextlog.setTtype(nextNode.getTtype());
                        nextlog.setUserId(firstLog.getUserId());
                        nextlog.setUserName(firstLog.getUserName());
                        nextlog.setDeptId(firstLog.getDeptId());
                        worklogMapper.insert(nextlog);

                        toUser.add(nextlog.getUserId()+"");
                        title = nextlog.getTitle()+" 已完成";
                        content = nextlog.getContent();
                        deptId = nextlog.getDeptId();

                    }else{
                        //写入一条下一个待办记录
                        //获取经办人
                        SysOperatorBo operatorParam = new SysOperatorBo();
                        operatorParam.setNid(nextNode.getNid());
                        operatorParam.setType("0");
                        List<SysOperator> operators = operatorMapper.selectSysOperatorList(operatorParam);

                        if(operators != null && operators.size() > 0){
                            for(SysOperator op : operators){
                                SysWorklog nextlog = new SysWorklog();
                                nextlog.setLogid(IdUtil.simpleUUID());
                                nextlog.setWid(worklog.getWid());
                                nextlog.setNid(nextNode.getNid());
                                nextlog.setObjid(worklog.getObjid());
                                nextlog.setName(nextNode.getName());
                                nextlog.setBusstype(worklog.getBusstype());
                                nextlog.setRoute(worklog.getRoute());
                                nextlog.setOtype(nextNode.getOtype());
                                nextlog.setOperatorid(op.getObjid());
                                nextlog.setOname(op.getName());
                                nextlog.setTitle(worklog.getTitle());
                                nextlog.setContent(worklog.getUserName()+" "+process.getName()+" "+worklog.getTitle()+",请及时处理。");
                                nextlog.setStatus("0");//待办
                                nextlog.setPrelogid(worklog.getLogid());
                                nextlog.setPreid(worklog.getUserId());
                                nextlog.setPrenid(worklog.getNid());
                                nextlog.setPid(nextProcess.getPid());
                                nextlog.setTtype(nextNode.getTtype());
                                nextlog.setDeptId(worklog.getDeptId());
                                worklogMapper.insert(nextlog);
                                toUser.addAll(getOperators(nextlog.getOtype(),nextlog.getOperatorid().toString()));
                                title = nextlog.getTitle();
                                content = nextlog.getContent();
                                deptId = nextlog.getDeptId();
                            }
                        }
                    }
                    processMapper.updateById(nextProcess);
//                    result = nextProcess;
                }

                break;
            case "2"://不通过：结束 生成一条待办记录 将节点流程直接进入到结束

                //获取结束节点
                lqw = Wrappers.lambdaQuery();
                lqw.eq(SysProcess::getBussid,worklog.getObjid());
                lqw.orderByDesc(SysProcess::getSeq);

                List<SysProcess> list = processMapper.selectList(lqw);
                SysProcess endProcess = list.get(0);

                SysNode nextNode = nodeMapper.selectById(endProcess.getNid());

                //获取发起人信息
                lqw = Wrappers.lambdaQuery();
                lqw.eq(SysProcess::getBussid,worklog.getObjid());
                lqw.orderByAsc(SysProcess::getSeq);

                List<SysProcess> plist = processMapper.selectList(lqw);
                SysProcess startProcess = plist.get(0);
                LambdaQueryWrapper<SysWorklog> wlqw = Wrappers.lambdaQuery();
                wlqw.eq(SysWorklog::getPid,startProcess.getPid());
                wlqw.orderByAsc(SysWorklog::getCreateTime);

                List<SysWorklog> wlogs = worklogMapper.selectList(wlqw);

                SysWorklog firstLog = wlogs.get(0);

                newLog.setLogid(IdUtil.simpleUUID());
                newLog.setWid(worklog.getWid());
                newLog.setNid(nextNode.getNid());
                newLog.setObjid(worklog.getObjid());
                newLog.setName(nextNode.getName());
                newLog.setBusstype(worklog.getBusstype());
                newLog.setRoute(worklog.getRoute());
                newLog.setOtype(firstLog.getOtype());
                newLog.setOperatorid(firstLog.getOperatorid());
                newLog.setOname(firstLog.getOname());
                newLog.setTitle(worklog.getTitle());
                newLog.setContent(
                    preLog.getTitle()+
                        " "+worklog.getUserName()+" "+
                        process.getName()+
                        " 无需处理"+(StringUtils.isNotBlank(worklog.getMemo())?"【"+worklog.getMemo()+"】":"")+
                        ",请及时关注。");
                worklog.setContent(worklog.getUserName()+
                    " 无需处理 "+preLog.getTitle()+(StringUtils.isNotBlank(worklog.getMemo())?"【"+worklog.getMemo()+"】":"")+
                    "。");
                newLog.setStatus("0");//已办
                newLog.setAction(worklog.getAction());
                newLog.setPrelogid(worklog.getLogid());
                newLog.setPreid(worklog.getUserId());
                newLog.setPrenid(worklog.getNid());
                newLog.setPid(endProcess.getPid());
                newLog.setTtype(nextNode.getTtype());
                newLog.setUserId(firstLog.getUserId());
                newLog.setUserName(firstLog.getUserName());
                newLog.setDeptId(firstLog.getDeptId());
                worklogMapper.insert(newLog);
                endProcess.setStatus("1");
                processMapper.updateById(endProcess);
//                result = endProcess;

                toUser.add(newLog.getUserId()+"");
                title = preLog.getTitle()+" 无需处理";
                content = newLog.getContent();
                deptId = preLog.getDeptId();

//                BeanUtil.copyProperties(preLog,newLog);
//                newLog.setLogid(IdUtil.simpleUUID());
//                newLog.setCreateBy(null);
//                newLog.setCreateTime(null);
//                newLog.setUpdateBy(null);
//                newLog.setUpdateTime(null);
//                newLog.setContent(
//                    preLog.getTitle()+
//                        " "+worklog.getUserName()+" "+
//                        process.getName()+
//                        " 不通过"+(StringUtils.isNotBlank(worklog.getMemo())?"【"+worklog.getMemo()+"】":"")+
//                        ",请及时关注。");
//                newLog.setStatus("0");//待办
////                newLog.setPrelogid(worklog.getLogid());
////                newLog.setPreid(worklog.getUserId());
////                newLog.setPrenid(worklog.getNid());
//                worklogMapper.insert(newLog);

                break;
            case "3"://转办  复制一条当前的日志 给转办人
                process.setStatus("1");

                SysNode curNode = nodeMapper.selectById(process.getNid());
                BeanUtil.copyProperties(worklog,newLog);
                newLog.setOtype(worklog.getTtype());
                newLog.setOperatorid(worklog.getTid());
                if(curNode.getTtype().equals("0")){
                    newLog.setOname(userMapper.selectUserById(worklog.getTid()).getNickName());
                }else if(curNode.getTtype().equals("1")){
                    newLog.setOname(roleMapper.selectById(worklog.getTid()).getRoleName());
                }else if(curNode.getTtype().equals("2")){
                    newLog.setOname(deptMapper.selectById(worklog.getTid()).getDeptName());
                }
                newLog.setLogid(IdUtil.simpleUUID());
                newLog.setCreateBy(null);
                newLog.setCreateTime(null);
                newLog.setUpdateBy(null);
                newLog.setUpdateTime(null);
                newLog.setTitle("转办："+worklog.getTitle()+process.getName());
                newLog.setContent(
                    worklog.getUserName()+" 转办 "+
                    preLog.getTitle()+" "+process.getName()+" "+
                    (StringUtils.isNotBlank(worklog.getMemo())?"【"+worklog.getMemo()+"】":"")+
                    ",请及时处理。");
                worklog.setContent(worklog.getUserName()+" 提交转办 "+
                    preLog.getTitle()+" "+process.getName()+" "+
                    (StringUtils.isNotBlank(worklog.getMemo())?"【"+worklog.getMemo()+"】":"")+
                    "。");
                newLog.setStatus("0");//待办
                newLog.setPrelogid(worklog.getLogid());
                newLog.setPreid(worklog.getUserId());
                newLog.setPrenid(worklog.getNid());
                newLog.setDeptId(worklog.getDeptId());
                worklogMapper.insert(newLog);
                toUser.addAll(getOperators(newLog.getOtype(),newLog.getOperatorid().toString()));
                title = newLog.getTitle();
                content = newLog.getContent();
                deptId = newLog.getDeptId();
                break;
        }

        if(worklogvo.getPics() != null && worklogvo.getPics().size() > 0){
            String pic = "";
            for(SysOss oss : worklogvo.getPics()){
                oss.setBuss("Worklog");
                oss.setObjid(worklog.getLogid());
                sysOssMapper.updateById(oss);
                pic+=oss.getUrl()+",";
            }
            pic = pic.substring(0,pic.length() - 1);
            if(StringUtils.isEmpty(worklog.getPic())){
                worklog.setPic(pic);
            }
        }
        worklogMapper.updateById(worklog);
        processMapper.updateById(process);

        sendNotice(toUser,deptId,title,content);
        return result;
    }

    /**
     * 终止流程
     * 1、先获取当前待办任务，设置为已办 备注为主动作废；
     * 2、将关联当前流程节点设置为已执行，备注为主动作废；
     * 3、将流程终止节点设置为当前；
     * @param type
     * @param bussid
     * @param mid
     * @return
     */
    @Override
    public Boolean endModelWorkflow(String type, String bussid, String mid) {
        Long operator = LoginHelper.getUserId();
        SysUser user = userMapper.selectUserById(operator);
        LambdaQueryWrapper<SysWorklog> logParam = Wrappers.lambdaQuery();
        logParam.eq(SysWorklog::getBusstype,type);
        logParam.eq(SysWorklog::getObjid,bussid);
        logParam.eq(SysWorklog::getStatus,"0");
        SysWorklog worklog = worklogMapper.selectOne(logParam);
        if(worklog != null){
            worklog.setUserId(user.getUserId());
            worklog.setUserName(user.getNickName());
            worklog.setDeptId(user.getDeptId());
            worklog.setStatus("1");//已办
            worklog.setMemo(user.getNickName()+" 执行了作废，终止流程。");
            worklogMapper.updateById(worklog);

            SysProcess process = processMapper.selectById(worklog.getPid());
            process.setStatus("2");
            process.setActime(new Date());
            process.setAction("2");
            process.setRemark(user.getNickName()+" 执行了作废，终止流程。");
            processMapper.updateById(process);
        }

        LambdaQueryWrapper<SysProcess> processParam = Wrappers.lambdaQuery();
        processParam.eq(SysProcess::getBussid,bussid);
        processParam.orderByDesc(SysProcess::getSeq);
        List<SysProcess> processes = processMapper.selectList(processParam);
        if(processes != null && processes.size() > 0){
            SysProcess end = processes.get(0);
            end.setStatus("1");
            end.setOperator(user.getNickName());
            end.setActime(new Date());
            end.setAction("2");
            end.setRemark(user.getNickName()+" 执行了作废，终止流程。");
            processMapper.updateById(end);
        }
        return true;
    }

    /**
     * 完成流程
     *
     * @param type
     * @param bussid
     * @param mid
     * @return
     */
    @Override
    public Boolean finishModelWorkflow(String type, String bussid, String mid) {
        Long operator = LoginHelper.getUserId();
        SysUser user = userMapper.selectUserById(operator);
        LambdaQueryWrapper<SysWorklog> logParam = Wrappers.lambdaQuery();
        logParam.eq(SysWorklog::getBusstype,type);
        logParam.eq(SysWorklog::getObjid,bussid);
        logParam.eq(SysWorklog::getStatus,"0");
        SysWorklog worklog = worklogMapper.selectOne(logParam);
        if(worklog != null){
            worklog.setUserId(user.getUserId());
            worklog.setUserName(user.getNickName());
            worklog.setDeptId(user.getDeptId());
            worklog.setStatus("1");//已办
            worklog.setMemo(user.getNickName()+" 重新提交，结束流程。");
            worklogMapper.updateById(worklog);

            SysProcess process = processMapper.selectById(worklog.getPid());
            process.setStatus("2");
            process.setActime(new Date());
            process.setAction("2");
            process.setRemark(user.getNickName()+" 重新提交，结束流程。");
            processMapper.updateById(process);
        }

        LambdaQueryWrapper<SysProcess> processParam = Wrappers.lambdaQuery();
        processParam.eq(SysProcess::getBussid,bussid);
        processParam.orderByDesc(SysProcess::getSeq);
        List<SysProcess> processes = processMapper.selectList(processParam);
        if(processes != null && processes.size() > 0){
            SysProcess end = processes.get(0);
            end.setStatus("2");
            end.setOperator(user.getNickName());
            end.setActime(new Date());
            end.setAction("2");
            end.setRemark(user.getNickName()+" 重新提交，结束流程。");
            processMapper.updateById(end);
        }
        return true;
    }

    public List<String> getOperators(String type,String objid){
        List<String> result = new ArrayList<>();
        switch (type){
            case "0":
                result.add(objid);
                break;
            case "1":
                Map<String,Object> roleUsers = userMapper.getUserIds(null,Long.valueOf(objid));
                if(roleUsers != null && roleUsers.get("ids") != null && !StringUtils.isEmpty(roleUsers.get("ids").toString())){
                    result = new ArrayList<String>(Arrays.asList(roleUsers.get("ids").toString().split(","))) ;
                }
                break;
            case "2":
                Map<String,Object> deptUsers = userMapper.getUserIds(Long.valueOf(objid),null);
                if(deptUsers != null && deptUsers.get("ids") != null && !StringUtils.isEmpty(deptUsers.get("ids").toString())){
                    result = new ArrayList<String>(Arrays.asList(deptUsers.get("ids").toString().split(","))) ;
                }
                break;
        }
        return result;
    }

    public boolean checkDatas(String objid,String prelogid,String otype,String oname,String operatorid){
        LambdaQueryWrapper<SysWorklog> logParam = Wrappers.lambdaQuery();
        logParam.eq(SysWorklog::getPrelogid,prelogid);
        logParam.eq(SysWorklog::getObjid,objid);
        logParam.eq(SysWorklog::getOtype,otype);
        logParam.eq(SysWorklog::getOname,oname);
        logParam.eq(SysWorklog::getStatus,"0");
        SysWorklog enty = worklogMapper.selectOne(logParam);
        if(enty  != null){
            return true;
        }
        return false;
    }

    public void sendNotice(List<String> toUsers,Long deptId,String title,String content){
        if(toUsers != null && toUsers.size() > 0){
            SysNotice notice = new SysNotice();
            notice.setNoticeType("1");//通知
            notice.setNoticeTitle(title);
            notice.setDeptId(deptId);
            notice.setNoticeContent(content);
            notice.setStatus("0");
            notice.setUserIds(String.join(",",toUsers));
            noticeMapper.insert(notice);

            toUsers.forEach(item->{
                NoticeUser user = new NoticeUser();
                user.setUserId(Long.valueOf(item));
                user.setNoticeId(notice.getNoticeId());
                user.setStatus("0");
                noticeUserMapper.insert(user);

                SysUser sysUser = userMapper.selectUserById(user.getUserId());
                if(StringUtils.isNotBlank(sysUser.getDeviceId())){
                    //消息对象
                    PushContent pushContent = new PushContent();
                    pushContent.setTitle(title);
                    pushContent.setContent(content);
                    PushUtils.pushMsg(sysUser.getDeviceId(), pushContent);
                }
            });
        }
    }

    public void pushMsg(String title,String content,List<String> objid,String type){

    }
}
